package com.dyzx.hbb.security.service.impl;

import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.dyzx.hbb.common.base.Result;
import com.dyzx.hbb.common.config.MyLambdaQueryWrapper;
import com.dyzx.hbb.common.utils.JwtUtils;
import com.dyzx.hbb.modules.sys.entity.SysLogLogin;
import com.dyzx.hbb.modules.sys.entity.SysUser;
import com.dyzx.hbb.modules.sys.service.SysLogLoginService;
import com.dyzx.hbb.modules.sys.service.SysOrderService;
import com.dyzx.hbb.modules.sys.service.SysUserService;
import com.dyzx.hbb.security.model.LoginUser;
import com.dyzx.hbb.security.model.LoginUserInfo;
import com.dyzx.hbb.security.model.SysUserInfo;
import com.dyzx.hbb.security.service.AuthService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.security.authentication.*;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContext;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;

import java.util.Map;
import java.util.concurrent.TimeUnit;

/**
 * 认证服务实现类
 */
@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private JwtUtils jwtUtils;

    @Autowired
    private SysUserService userService;

    @Autowired
    private SysLogLoginService logLoginService;

    @Autowired
    private SysOrderService orderService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

  //  @CacheEvict(value = "token::userCache")
    @Override
    public Result<SysUserInfo> login(String username, String password) {
        try {
            System.out.println("login");
            System.out.println(username);
            System.out.println(password);
            // 参数校验
            if (username == null || password == null) {
                return Result.error("用户名和密码不能为空");
            }

            // 用户验证
            Authentication authentication = authenticationManager.authenticate(
                    new UsernamePasswordAuthenticationToken(username, password));

            // 生成token
            LoginUser loginUser = (LoginUser) authentication.getPrincipal();
            SysUser user = loginUser.getUser();

            // 检查用户状态
            if (user.getStatus() != null && user.getStatus() == 0) {
                return Result.error("账号已被禁用");
            }
            SysUserInfo userInfo = userService.getLoginUserInfo(user.getId());
            Map<String, Object> map = orderService.findByOrderInfo(user.getOrganId());
            userInfo.setOrder(map);
            String token = jwtUtils.generateToken(user.getId(), String.valueOf(loginUser.getUsername()));
            Long expiration = jwtUtils.getExpiration(token);
            userInfo.setToken(token);
            SysLogLogin sysLogLogin = new SysLogLogin();
            sysLogLogin.setUserId(user.getId());
            sysLogLogin.setAccount(user.getAccount());
            sysLogLogin.setToken(token);
            sysLogLogin.setExpireDate(expiration);
            //  sysLogLogin.setCreateDate(System.currentTimeMillis());
            //  sysLogLogin.setId(user.getIp());
            sysLogLogin.setToken(token);
            //   sysLogLogin.setBrowser(user.getBrowser());
            //   sysLogLogin.setSystemName(user.getSystemName());
            sysLogLogin.setCreateDate(System.currentTimeMillis());
            sysLogLogin.setOrganId(user.getOrganId());
            logLoginService.save(sysLogLogin);
            return Result.ok(userInfo);

        } catch (Exception e) {
            e.printStackTrace();
            String errorMsg = "用户名或密码错误";
            if (e instanceof UsernameNotFoundException) {
                errorMsg = "用户不存在";
            } else if (e instanceof BadCredentialsException) {
                errorMsg = "密码错误";
            } else if (e instanceof DisabledException) {
                errorMsg = "账号已被禁用";
            } else if (e instanceof LockedException) {
                errorMsg = "账号已被锁定";
            }
            return Result.error(errorMsg);
        }
    }


    @Override
    public Result<Void> logout() {
        Long userId = com.dyzx.hbb.security.context.SecurityContextHolder.getUserId();

        if (userId != null) {
           forceOut(userId);
        }

        SecurityContextHolder.clearContext();

        return Result.ok();
    }

    @Override
    public boolean forceOut(Long userId) {
        LambdaUpdateWrapper<SysLogLogin> queryWrapper = new LambdaUpdateWrapper<>();
        queryWrapper.eq(SysLogLogin::getUserId, userId);
        queryWrapper.set(SysLogLogin::getDeleted, 1);
        return logLoginService.update(queryWrapper);
    }

    @Override
    public Result<Void> register(SysUser user) {
        // 参数校验
        if (user.getAccount() == null || user.getPassword() == null) {
            return Result.error("用户名和密码不能为空");
        }

        // 检查用户名是否已存在
        if (userService.getByAccount(user.getAccount()) != null) {
            return Result.error("用户名已存在");
        }

        // 设置默认值
        user.setStatus(1);


        // 保存用户
        if (userService.save(user)) {
            return Result.ok();
        }
        return Result.error("注册失败");
    }

    @Override
    public LoginUser getLoginUser() {
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        if (authentication != null) {
            return (LoginUser) authentication.getPrincipal();
        }
        return null;
    }

    @Override
    public Result<LoginUserInfo> getCurrentUser() {
        LoginUser loginUser = getLoginUser();
        if (loginUser == null) {
            return Result.error("用户未登录");
        }
        LoginUserInfo userInfo = new LoginUserInfo(loginUser.getUser(), loginUser.getPermissions(), loginUser.getDataScope());
        return Result.ok(userInfo);
    }

    @Override
    public Result<SysUser> getProfile() {
        LoginUser loginUser = getLoginUser();
        if (loginUser == null) {
            return Result.error("用户未登录");
        }
        // 从数据库获取最新的用户信息
        SysUser user = userService.getById(loginUser.getUser().getId());
        if (user == null) {
            return Result.error("用户不存在");
        }
        return Result.ok(user);
    }

    @Cacheable(value = "token::userCache", key = "#token")
    @Override
    public boolean validateToken(String token) {
        long l = System.currentTimeMillis();

        MyLambdaQueryWrapper<SysLogLogin> queryWrapper = new MyLambdaQueryWrapper<>();
        queryWrapper.eq(SysLogLogin::getToken, token);
        queryWrapper.eq(SysLogLogin::getDeleted, 0).ge(SysLogLogin::getExpireDate, l);
        queryWrapper.last("limit 1");
        SysLogLogin one = logLoginService.getOne(queryWrapper);
        if(one != null){
            long l1 = one.getExpireDate() - l;
            JSONObject from = JSONObject.from(one);
            stringRedisTemplate.opsForValue().set(token, from.toJSONString(), l1, TimeUnit.MILLISECONDS);
            return true;
        }


        return false;
      //  return   logLoginService.exists(queryWrapper);

    }


}